//基于axios的封装网络请求
import router from "@/router";
import theAxios from "axios";
import { Warning } from "postcss";
import { Notify } from "vant";
import { getToken, removeToken, setToken } from "./token";
import { reFreshTokenAPI } from "@/api";

const axios = theAxios.create({
  //基地址
  baseURL: "http://toutiao.itheima.net/",
  timeout: 20000, //超时时间为20s
});

// 添加请求拦截器
axios.interceptors.request.use(
  function (config) {
    // 在发送请求之前做些什么
    //可以在请求之前，检查是否本地有token，如果有并且没有携带给他携带上去
    // 功能 ：统一携带 token
    // 未定义即没有 为 undefined ，如果是有但是没有赋值，显示为null
    if (getToken() && config.headers.Authorization === undefined) {
      config.headers.Authorization = `Bearer ${getToken()}`;
    }
    return config;
  },
  function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
  }
);

//从后返回数据到前端叫做响应，要经过拦截器才能到前端
// 添加响应拦截器
axios.interceptors.response.use(
  function (response) {
    // 对响应数据做点什么
    return response;
  },
  async function (error) {
    // 里面 4xx 5xx 的时候会返回里面error回来
    // 对响应错误做点什么
    console.log(error);
    //在这里进行判断，告知永不，如果出现 401 给它提示信息，让他重新登录
    if (error.response.status === 401) {
      //不能使用 this.$router 是因为这里不是vue所管理的实例
      Notify({ type: "warning", message: "身份过期，请重新登录" });
      //移除token，才能让路由守卫放行
      removeToken();
      // 方式1 ,登录过期之后，重新获取token，用户有感知

      // router.replace('/login')

      // 方式2: 使用refresh_token 用户没有感知
      const res = await reFreshTokenAPI();
      // 1.更新token在本地
      setToken(res.data.data.token);
      // 2.更新新的token在请求头
      error.config.headers.Authorization = `Bearer ${res.data.data.token}`;
      //2.未完成的请求再次发起
      //error.config 上一次请求的配置信息
      return axios(error.config);
      // console.log(res);
      //如果 refresh_token  也过期
    } else if (
      error.response.status === 500 &&
      error.config.url === "/v1_0/authorizations" &&
      error.config.method === "put"
    ) {
      Notify({ type: "warning", message: "身份过期，请重新登录" });

      localStorage.clear(); //清除所有值
      router.replace("/login");
    }
    return Promise.reject(error);
  }
);

export default ({
  url,
  method = "GET",
  params = {},
  data = {},
  headers = {},
}) => {
  return axios({
    url,
    method,
    params,
    data,
    headers,
  });
};
